package feces.servlet;

import java.io.IOException;
import java.util.List;

import javax.persistence.EntityTransaction;
import javax.persistence.RollbackException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import feces.model.Product;
import feces.model.Storehouse;
import feces.model.StorehouseProduct;
import feces.utility.Utility;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * 仓库管理伺服器
 * 
 * @author Bromine0x23
 */
@WebServlet(name = "storehouse", urlPatterns = { "/api/storehouse" })
@NoArgsConstructor
public class StorehouseServlet extends RESTfulServlet {

	private static final long serialVersionUID = -2737624564496333063L;

	/**
	 * 字典
	 * 
	 * @author Bromine0x23
	 */
	@NoArgsConstructor(access = AccessLevel.PROTECTED)
	public static final class Dictionary extends RESTfulServlet.Dictionary {
		
		public static final String NAME = "name";
		
		public static final String ADDRESS = "address";
		
		public static final String MANAGER = "manager";
		
		public static final String TYPE = "type";
	}
	
	/**
	 * 响应POST请求
	 * 创建库房
	 * 
	 * @return 商品代码
	 */
	@Override
	protected Response<Storehouse> responseCreate(
		HttpServletRequest request,
		HttpServletResponse response
	) throws ServletException, IOException {
		final Storehouse storehouse = new Storehouse();
		storehouse.setName(request.getParameter(Dictionary.NAME));
		storehouse.setAddress(request.getParameter(Dictionary.ADDRESS));
		storehouse.setManager(request.getParameter(Dictionary.MANAGER));
		storehouse.setType(Utility.toEnum(Storehouse.Type.class, request.getParameter(Dictionary.TYPE)));
		if (storehouse.isValid()) {
			boolean result = doTransaction(new Runnable() {

				@Override
				public void run() {
					add(storehouse);
					for (Product product : findAll(Product.class)) {
						StorehouseProduct storehouse_product = new StorehouseProduct();
						storehouse_product.setStorehouseId(storehouse.getId());
						storehouse_product.setProductId(product.getId());
						storehouse_product.setQuantity(0);
						storehouse_product.setCritical(0);
						storehouse_product.setLimit(0);
						add(storehouse_product);
					}
				}

			});
			if (result) {
				return succeed(storehouse);
			}
			return exception(null);
		}
		return failed(null);
	}
	
	/**
	 * 响应DELETE请求
	 * 删除库房
	 * 
	 * @return 操作结果
	 */
	@Override
	protected Response<Boolean> responseDelete(
		HttpServletRequest request,
		HttpServletResponse response
	) throws ServletException, IOException {
		String parameter = request.getParameter(Dictionary.ID);
		if (parameter == null) {
			return invalid("未设置主键", false);
		}
		Integer id = Utility.toInteger(parameter);
		if (id == null) {
			return invalid("主键非法", false);
		}
		final Storehouse storehouse = find(Storehouse.class, id);
		boolean result = doTransaction(new Runnable() {

			@Override
			public void run() {
				List<StorehouseProduct> storehouse_products = executeQuery(
					"SELECT p FROM StorehouseProduct p WHERE p.storehouseId = ?1",
					StorehouseProduct.class,
					storehouse.getId()
				);
				for (StorehouseProduct storehouse_product : storehouse_products) {
					remove(storehouse_product);
				}
				remove(storehouse);
			}

		});
		return result ? succeed("删除成功", true) : exception("删除失败，可能有关联数据未清除", false);
	}
	
	/**
	 * 响应GET请求
	 * 获取库房
	 * 
	 * @return 查询结果，可能为空
	 */
	@Override
	protected Response<Storehouse> responseRead(
		HttpServletRequest request,
		HttpServletResponse response
	) throws ServletException, IOException {
		return responseReadBasic(request, Storehouse.class);
	}
	
	/**
	 * 响应PUT请求 修改商品二级分类
	 * 
	 * @return 操作结果
	 */
	@Override
	protected Response<Storehouse> responseUpdate(
		HttpServletRequest request,
		HttpServletResponse response
	) throws ServletException, IOException {
		Integer id = Utility.toInteger(request.getParameter(Dictionary.PK));
		if (id == null) {
			return invalid("主键不能为空", null);
		}
		final Storehouse storehouse = find(Storehouse.class, id);
		String column = request.getParameter(Dictionary.COLUMN);
		String value = request.getParameter(Dictionary.VALUE);
		if (storehouse == null) {
			return invalid("无效的主键", null);
		}
		if (Utility.isEmpty(column)) {
			return invalid("修改域不能为空", null);
		}
		EntityTransaction transaction = getTransaction();
		try {
			transaction.begin();
			switch (column) {
				case Dictionary.NAME: {
					storehouse.setName(value);
					break;
				}
				case Dictionary.ADDRESS: {
					storehouse.setAddress(value);
					break;
				}
				case Dictionary.MANAGER: {
					storehouse.setManager(value);
					break;
				}
				case Dictionary.TYPE: {
					storehouse.setType(Utility.toEnum(Storehouse.Type.class, value));
					break;
				}
				default:
					return invalid("无效的修改域", null);
			}
			if (storehouse.isValid()) {
				transaction.commit();
				return succeed("修改成功", storehouse);
			}
		} catch (IllegalStateException | RollbackException exception){
			return exception("执行发生异常", null);
		} finally {
			if (transaction.isActive()) {
				transaction.rollback();
			}
		}
		return failed("修改失败", null);
	}
}
